package com.lineage.server.model.Instance;

import com.lineage.server.datatables.DoorSpawnTable;
import com.lineage.server.model.L1AttackPc;
import com.lineage.server.model.L1Character;
import com.lineage.server.model.L1Object;
import com.lineage.server.serverpackets.S_DoActionGFX;
import com.lineage.server.serverpackets.S_Door;
import com.lineage.server.serverpackets.S_DoorPack;
import com.lineage.server.serverpackets.S_RemoveObject;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.templates.L1Npc;
import com.lineage.server.thread.GeneralThreadPool;
import com.lineage.server.types.Point;
import com.lineage.server.world.World;
import java.util.Iterator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1DoorInstance extends L1NpcInstance {
  private static final long serialVersionUID = 1L;
  
  public static final int PASS = 0;
  
  public static final int NOT_PASS = 65;
  
  private static final Log _log = LogFactory.getLog(L1DoorInstance.class);
  
  private int _doorId;
  
  private int _direction;
  
  private int _leftEdgeLocation;
  
  private int _rightEdgeLocation;
  
  private int _openStatus;
  
  private int _passable;
  
  private int _keeperId;
  
  private int _crackStatus;
  
  public L1DoorInstance(L1Npc template) {
    super(template);
    this._doorId = 0;
    this._direction = 0;
    this._leftEdgeLocation = 0;
    this._rightEdgeLocation = 0;
    this._openStatus = 29;
    this._passable = 65;
    this._keeperId = 0;
  }
  
  public void onAction(L1PcInstance pc) {
    try {
      if (getMaxHp() == 0 || getMaxHp() == 1)
        return; 
      if (getCurrentHp() > 0 && !isDead()) {
        L1AttackPc l1AttackPc = new L1AttackPc(pc, this);
        if (l1AttackPc.calcHit())
          l1AttackPc.calcDamage(); 
        l1AttackPc.action();
        l1AttackPc.commit();
      } 
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void onPerceive(L1PcInstance perceivedFrom) {
    try {
      if (perceivedFrom.get_showId() != get_showId())
        return; 
      perceivedFrom.addKnownObject((L1Object)this);
      if (getOpenStatus() == 28) {
        setOpenStatus(28);
        setPassable(0);
      } else {
        setOpenStatus(29);
        setPassable(65);
      } 
      perceivedFrom.sendPackets((ServerBasePacket)new S_DoorPack(this));
      sendDoorPacket();
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void deleteMe() {
    try {
      setPassable(0);
      sendDoorPacket();
      this._destroyed = true;
      if (getInventory() != null)
        getInventory().clearItems(); 
      allTargetClear();
      this._master = null;
      World.get().removeVisibleObject((L1Object)this);
      World.get().removeObject((L1Object)this);
      Iterator<L1PcInstance> iterator = World.get().getRecognizePlayer((L1Object)this).iterator();
      while (iterator.hasNext()) {
        L1PcInstance pc = iterator.next();
        pc.removeKnownObject((L1Object)this);
        pc.sendPackets((ServerBasePacket)new S_RemoveObject((L1Object)this));
      } 
      removeAllKnownObjects();
    } catch (Exception e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void receiveDamage(L1Character attacker, int damage) {
    if (getMaxHp() == 0 || getMaxHp() == 1)
      return; 
    if (getCurrentHp() > 0 && !isDead()) {
      int newHp = getCurrentHp() - damage;
      if (newHp <= 0 && !isDead()) {
        setStatus(37);
        Death death = new Death(attacker);
        GeneralThreadPool.get().execute(death);
      } 
      if (newHp > 0) {
        setCurrentHp(newHp);
        if (getMaxHp() * 1 / 6 > getCurrentHp()) {
          if (this._crackStatus != 5) {
            broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 36));
            setStatus(36);
            this._crackStatus = 5;
          } 
        } else if (getMaxHp() * 2 / 6 > getCurrentHp()) {
          if (this._crackStatus != 4) {
            broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 35));
            setStatus(35);
            this._crackStatus = 4;
          } 
        } else if (getMaxHp() * 3 / 6 > getCurrentHp()) {
          if (this._crackStatus != 3) {
            broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 34));
            setStatus(34);
            this._crackStatus = 3;
          } 
        } else if (getMaxHp() * 4 / 6 > getCurrentHp()) {
          if (this._crackStatus != 2) {
            broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 33));
            setStatus(33);
            this._crackStatus = 2;
          } 
        } else if (getMaxHp() * 5 / 6 > getCurrentHp() && this._crackStatus != 1) {
          broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 32));
          setStatus(32);
          this._crackStatus = 1;
        } 
      } 
    } else if (!isDead()) {
      setStatus(37);
      Death death2 = new Death(attacker);
      GeneralThreadPool.get().execute(death2);
    } 
  }
  
  public void setCurrentHp(int i) {
    int currentHp = Math.min(i, getMaxHp());
    if (getCurrentHp() == currentHp)
      return; 
    setCurrentHpDirect(currentHp);
  }
  
  private void sendDoorPacket() {
    int entranceX = getEntranceX();
    int entranceY = getEntranceY();
    int leftEdgeLocation = getLeftEdgeLocation();
    int rightEdgeLocation = getRightEdgeLocation();
    int size = rightEdgeLocation - leftEdgeLocation;
    if (size == 0) {
      sendPacket(entranceX, entranceY);
    } else if (getDirection() == 0) {
      int x = leftEdgeLocation;
      while (x <= rightEdgeLocation) {
        sendPacket(x, entranceY);
        x++;
      } 
    } else {
      int y = leftEdgeLocation;
      while (y <= rightEdgeLocation) {
        sendPacket(entranceX, y);
        y++;
      } 
    } 
  }
  
  private void sendPacket(int x, int y) {
    S_Door packet = new S_Door(x, y, getDirection(), getPassable());
    broadcastPacketAll((ServerBasePacket)packet);
  }
  
  public void open() {
    if (isDead())
      return; 
    if (getOpenStatus() == 29) {
      setOpenStatus(28);
      setPassable(0);
      broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 28));
      sendDoorPacket();
    } 
  }
  
  public void close() {
    if (isDead())
      return; 
    if (getOpenStatus() == 28) {
      setOpenStatus(29);
      setPassable(65);
      broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(getId(), 29));
      sendDoorPacket();
    } 
  }
  
  public void repairGate() {
    if (getMaxHp() > 1) {
      setDead(false);
      setCurrentHp(getMaxHp());
      setStatus(0);
      setCrackStatus(0);
      setOpenStatus(28);
      close();
    } 
  }
  
  public int getDoorId() {
    return this._doorId;
  }
  
  public void setDoorId(int i) {
    this._doorId = i;
  }
  
  public int getDirection() {
    return this._direction;
  }
  
  public void setDirection(int i) {
    if (i == 0 || i == 1)
      this._direction = i; 
  }
  
  public int getEntranceX() {
    int entranceX = 0;
    if (getDirection() == 0) {
      entranceX = getX();
    } else {
      entranceX = getX() - 1;
    } 
    return entranceX;
  }
  
  public int getEntranceY() {
    int entranceY = 0;
    if (getDirection() == 0) {
      entranceY = getY() + 1;
    } else {
      entranceY = getY();
    } 
    return entranceY;
  }
  
  public int getLeftEdgeLocation() {
    return this._leftEdgeLocation;
  }
  
  public void setLeftEdgeLocation(int i) {
    this._leftEdgeLocation = i;
  }
  
  public int getRightEdgeLocation() {
    return this._rightEdgeLocation;
  }
  
  public void setRightEdgeLocation(int i) {
    this._rightEdgeLocation = i;
  }
  
  public int getOpenStatus() {
    return this._openStatus;
  }
  
  public void setOpenStatus(int i) {
    if (i == 28 || i == 29)
      this._openStatus = i; 
  }
  
  public int getPassable() {
    return this._passable;
  }
  
  private void setPassable(int i) {
    if (i == 0 || i == 65)
      this._passable = i; 
  }
  
  public int getKeeperId() {
    return this._keeperId;
  }
  
  public void setKeeperId(int i) {
    this._keeperId = i;
  }
  
  private void setCrackStatus(int i) {
    this._crackStatus = i;
  }
  
  public static void openDoor() {
    L1DoorInstance[] allDoor = DoorSpawnTable.get().getDoorList();
    if (allDoor.length <= 0)
      return; 
    L1DoorInstance[] arrayOfL1DoorInstance1 = allDoor;
    int j = allDoor.length;
    int i = 0;
    while (i < j) {
      L1DoorInstance door = arrayOfL1DoorInstance1[i];
      switch (door.getDoorId()) {
        case 5001:
        case 5002:
        case 5003:
        case 5004:
        case 5005:
        case 5006:
        case 5007:
        case 5008:
        case 5009:
        case 5010:
        case 6006:
        case 6007:
        case 10000:
        case 10001:
        case 10002:
        case 10003:
        case 10004:
        case 10005:
        case 10006:
        case 10007:
        case 10008:
        case 10009:
        case 10010:
        case 10011:
        case 10012:
        case 10013:
        case 10015:
        case 10016:
        case 10017:
        case 10019:
        case 10020:
        case 10036:
          door.close();
          break;
        default:
          if (door.getMaxHp() > 1) {
            door.close();
            break;
          } 
          if (door.getKeeperId() != 0) {
            door.close();
            break;
          } 
          door.open();
          break;
      } 
      i++;
    } 
  }
  
  public static void openGam(boolean isOpen) {
    L1DoorInstance[] allDoor = DoorSpawnTable.get().getDoorList();
    if (allDoor.length <= 0)
      return; 
    L1DoorInstance[] array;
    int length = (array = allDoor).length;
    int i = 0;
    while (i < length) {
      L1DoorInstance door = array[i];
      switch (door.getDoorId()) {
        case 51:
        case 52:
        case 53:
        case 54:
        case 55:
          if (isOpen) {
            door.open();
            break;
          } 
          door.close();
          break;
      } 
      i++;
    } 
  }
  
  class Death implements Runnable {
    L1Character _lastAttacker;
    
    public Death(L1Character lastAttacker) {
      this._lastAttacker = lastAttacker;
    }
    
    public void run() {
      L1DoorInstance.this.setCurrentHpDirect(0);
      L1DoorInstance.this.setDead(true);
      L1DoorInstance.this.getMap().setPassable((Point)L1DoorInstance.this.getLocation(), true);
      L1DoorInstance.this.broadcastPacketAll((ServerBasePacket)new S_DoActionGFX(L1DoorInstance.this.getId(), 37));
      L1DoorInstance.this.setPassable(0);
      L1DoorInstance.this.setOpenStatus(28);
      L1DoorInstance.this.setPassable(0);
      L1DoorInstance.this.sendDoorPacket();
    }
  }
}
